#define _CRT_NON_CONFORMING_SWPRINTFS
#include "libutilsconfig.h"
#include "tCallStack.h"
#include "tDictionary.h"
#include "uStringUtils.h"
#include "texceptionex.h"

//#include "boost/lexical_cast.hpp"
//#include "Exceptions.h"
#include <algorithm>
//#include "lib_localcompile.h"

LIB_NS_BEGIN

tstring String_Strip( const tstring& value )
{
	if( !value.size() )
		return value;

	int32 startPos = value.find_first_not_of(_T(" \t\r\n"));
	int32 endPos = value.find_last_not_of(_T(" \t\r\n"));

	if( startPos == -1 )
		return value;

	return tstring(value, startPos, endPos - startPos + 1 );
}

tstring TDictionary::GetString(const tstring& key,bool capitalize ) const
{ 
	Data::const_iterator i = m_data.find( UStrConvUtils::ToUpper(key) );
	if( i == m_data.end() ) 
		throw TException( (key + _T(" not defined") ).c_str());

	tstring result = i->second;
	if(capitalize )
		std::transform(result.begin(), result.end(), result.begin(), toupper);

	return result;  
}


int32 TDictionary::GetInt32(const tstring& key ) const
{ 
	Data::const_iterator i = m_data.find( UStrConvUtils::ToUpper(key) );
	if ( i == m_data.end() ) 
		throw TException( key + _T(" not defined") );
	try
	{
		return _tstoi( i->second.c_str() );
	}
	catch ( ... )
	{
		throw TException( ( tstring(_T("Illegal value ")) + i->second + _T(" for ") + key ).c_str());
	}
}

double TDictionary::GetDouble( const tstring& key ) const
{ 
	Data::const_iterator i = m_data.find( UStrConvUtils::ToUpper(key) );
	if ( i == m_data.end() ) 		
		throw TException( (key + _T(" not defined" )).c_str());

	try
	{
		return _tstof( i->second.c_str() );
	}
	catch ( ... )
	{
		
		throw TException( (tstring(_T("Illegal value ")) + i->second + _T(" for ") + key ).c_str());
	}  
}

bool TDictionary::GetBool( const tstring& key ) const
{ 
	Data::const_iterator i = m_data.find( UStrConvUtils::ToUpper(key) );
	if ( i == m_data.end() ) 
		
		throw TException( ( key + _T(" not defined") ).c_str());
	try
	{
		return  i->second == _T("true") ?true  :false;
	}
	catch ( ... )
	{
		
		throw TException( (tstring(_T("Illegal value ")) + i->second + _T(" for ") + key ).c_str());
	}  
}

int32 TDictionary::GetDay( const tstring& key ) const
{ 
	Data::const_iterator i = m_data.find( UStrConvUtils::ToUpper(key) );
	if ( i == m_data.end() ) 
		
		throw TException( (key + _T(" not defined") ).c_str());

	try
	{
		tstring value = i->second;
		if( value.size() < 2 ) 
			throw TException(_T("0"));

		tstring abbr = value.substr(0, 2);
		std::transform( abbr.begin(), abbr.end(), abbr.begin(), tolower );
		if( abbr == _T("su" ) )
			return 1;
		if( abbr == _T("mo" ) )
			return 2;
		if( abbr == _T("tu" ) )
			return 3;
		if( abbr == _T("we" ) )
			return 4;
		if( abbr == _T("th" ) )
			return 5;
		if( abbr == _T("fr" ) )
			return 6;
		if( abbr == _T("sa" ) )
			return 7;
		if( value.size() < 2 ) 
			throw TException(_T("0"));
	}
	catch ( ...)
	{
		throw TException( (tstring(_T("Illegal value ")) + i->second + _T(" for ") + key ).c_str());
	}
	return -1;  
}

void TDictionary::SetString( const tstring& key, const tstring& value )
{ 
	m_data[String_Strip(UStrConvUtils::ToUpper(key)) ] = String_Strip(value);  
}

void TDictionary::SetInt32( const tstring& key, int32 value )
{ 
	TCHAR buff[64];
	_stprintf(buff,_T("%d"),value);
	m_data[String_Strip(UStrConvUtils::ToUpper(key))] = buff;
		//boost::lexical_cast<tstring,int32>(value);  
}

void TDictionary::SetDouble( const tstring& key, double value )
{ 
	TCHAR buff[64];
	_stprintf(buff,_T("%f"),value);
	m_data[String_Strip(UStrConvUtils::ToUpper(key)) ] = buff;
		//boost::lexical_cast<tstring,double>(value);
}

void TDictionary::SetBool( const tstring& key, bool value )
{ 
	m_data[String_Strip(UStrConvUtils::ToUpper(key))] = 
		value? _T("true") : _T("false");
		//boost::lexical_cast<tstring,bool>(value);
}

void TDictionary::SetDay( const tstring& key, int value )
{ 
	switch( value )
	{
	case 1:
		SetString( key, _T("SU" )); 
		break;
	case 2:
		SetString( key, _T("MO" )); 
		break;
	case 3:
		SetString( key, _T("TU" )); 
		break;
	case 4:
		SetString( key, _T("WE" )); 
		break;
	case 5:
		SetString( key, _T("TH" )); 
		break;
	case 6:
		SetString( key, _T("FR" )); 
		break;
	case 7:
		SetString( key, _T("SA" )); 
		break;
	}  
}

bool TDictionary::Has( const tstring& key ) const
{ 
	return m_data.find( UStrConvUtils::ToUpper(key) ) != m_data.end();
}

void TDictionary::Merge( const TDictionary& toMerge )
{ 
	Data::const_iterator i = toMerge.m_data.begin();
	for (;i != toMerge.m_data.end(); ++i )
	{
		if ( m_data.find( i->first ) == m_data.end() )
			m_data[ i->first ] = i->second;
	}
}

LIB_NS_END
